package com.avoid.easymqtt.common.algorithm;

/**
 * 一段时间窗口的包装器实体类。
 *
 * @author avoid@fiture.com
 * @date 2021/11/19
 * @motto Life is so short,do something to make yourself happy,such as coding
 */
public class WindowWrap<T> {

    /**
     * 单个窗口存储桶的时间长度（毫秒）。
     */
    private final long windowLengthInMs;

    /**
     * 窗口的开始时间戳（毫秒）。
     */
    private long windowStart;

    /**
     * 统计数据。
     */
    private T value;

    public WindowWrap(long windowLengthInMs, long windowStart, T value) {
        this.windowLengthInMs = windowLengthInMs;
        this.windowStart = windowStart;
        this.value = value;
    }

    public long windowLength() {
        return windowLengthInMs;
    }

    public long windowStart() {
        return windowStart;
    }

    public T value() {
        return value;
    }

    public void setValue(T value) {
        this.value = value;
    }

    /**
     * 将当前bucket的开始时间戳重置为开始的时间。
     *
     * @param startTime 有效的开始时间戳
     * @return 复位后的bucket
     */
    public WindowWrap<T> resetTo(long startTime) {
        this.windowStart = startTime;
        return this;
    }

    /**
     * 检查给定的时间戳是否在当前bucket中。
     *
     * @param timeMillis 有效时间戳（毫秒）
     * @return 如果给定时间在当前存储桶中，则为true，否则为false
     */
    public boolean isTimeInWindow(long timeMillis) {
        return windowStart <= timeMillis && timeMillis < windowStart + windowLengthInMs;
    }

    @Override
    public String toString() {
        return "WindowWrap{" + "windowLengthInMs=" + windowLengthInMs + ", windowStart=" + windowStart + ", value="
            + value + '}';
    }

}
